package exception

import (
	"lark/src/lexer"
	"strings"
	"sync"
)

type ErrorHandler struct {
	lexerErrors  []*LexerError
	ParseErrors  []*ParseError
	runtimeError *RuntimeError
	hadError     bool
	mu           sync.Mutex // 添加互斥锁保证并发安全
}

func NewErrorManager() *ErrorHandler {
	return &ErrorHandler{
		lexerErrors: make([]*LexerError, 0),
		ParseErrors: make([]*ParseError, 0),
	}
}

// Warn 输出警告信息
func (h *ErrorHandler) LexWarnError(message string, args ...interface{}) {
	lexErr := &LexerError{Message: message}
	if len(args) > 0 {
		lexErr.Code = args[0].(int)
	}
	if len(args) > 1 && args[1] != nil {
		lexErr.File = args[1].(string)
	}
	if len(args) > 2 && args[2] != nil {
		lexErr.Line = args[2].(int)
	}
	if len(args) > 3 && args[3] != nil {
		lexErr.Column = args[3].(int)
	}
	h.lexerErrors = append(h.lexerErrors, lexErr)
	h.hadError = true

}

// Error 输出错误信息
func (h *ErrorHandler) LexError(message string, args ...interface{}) {
	lexErr := &LexerError{Message: message}
	if len(args) > 0 {
		lexErr.Code = args[0].(int)
	}
	if len(args) > 1 && args[1] != nil {
		lexErr.File = args[1].(string)
	}
	if len(args) > 2 && args[2] != nil {
		lexErr.Line = args[2].(int)
	}
	if len(args) > 3 && args[3] != nil {
		lexErr.Column = args[3].(int)
	}
	h.lexerErrors = append(h.lexerErrors, lexErr)
	h.hadError = true
}

// Fatal 输出致命错误并退出
func (h *ErrorHandler) LexFatalError(message string, args ...interface{}) {
	lexErr := &LexerError{Message: message}
	if len(args) > 0 {
		lexErr.Code = args[0].(int)
	}
	if len(args) > 1 && args[1] != nil {
		lexErr.File = args[1].(string)
	}
	if len(args) > 2 && args[2] != nil {
		lexErr.Line = args[2].(int)
	}
	if len(args) > 3 && args[3] != nil {
		lexErr.Column = args[3].(int)
	}
	h.lexerErrors = append(h.lexerErrors, lexErr)
	h.hadError = true
}

// Warn 输出警告信息
func (h *ErrorHandler) ParseWarnError(message string, code int, token lexer.Token) {
	parseErr := &ParseError{
		Message: message,
		Code:    code,
		Line:    token.Line,
		Column:  token.Column,
	}
	h.ParseErrors = append(h.ParseErrors, parseErr)
	h.hadError = true

}

// Error 输出错误信息
func (h *ErrorHandler) ParseError(message string, code int, token lexer.Token) {
	h.mu.Lock()
	defer h.mu.Unlock()

	parseErr := &ParseError{
		Message: message,
		Code:    code,
		Line:    token.Line,
		Column:  token.Column,
	}
	/* if expected != nil {
		parseErr.Expected = expected
	} */

	h.ParseErrors = append(h.ParseErrors, parseErr)
	h.hadError = true
}

// Fatal 输出致命错误并退出
func (h *ErrorHandler) ParseFatalError(message string, code int, token lexer.Token) {
	parseErr := &ParseError{
		Message: message,
		Code:    code,
		Line:    token.Line,
		Column:  token.Column,
	}
	h.ParseErrors = append(h.ParseErrors, parseErr)
	h.hadError = true
}

// 运行时错误
func (h *ErrorHandler) RuntimeError(err *RuntimeError) {
	h.runtimeError = err
	h.hadError = true
}

func (h *ErrorHandler) HadError() bool {
	return h.hadError
}

// 格式化错误
func (h *ErrorHandler) FormatErrors() string {
	var sb strings.Builder
	for _, err := range h.lexerErrors {
		sb.WriteString(err.Error())
		sb.WriteString("\n")
	}
	for _, err := range h.ParseErrors {
		sb.WriteString(err.Error())
		sb.WriteString("\n")
	}
	if h.runtimeError != nil {
		sb.WriteString(h.runtimeError.Error())
		sb.WriteString("\n")
	}
	return sb.String()
}
